﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using Light.Utility.Security;

namespace Light.Utility
{
    /// <summary>
    /// Web请求辅助类
    /// </summary>
    public class WebHelper
    {

        #region Get、POST

        /// <summary>
        /// Post数据至目标url
        /// </summary>
        /// <param name="url">服务器URL</param>
        /// <param name="data">要发送的参数字符串</param>
        /// <param name="encoding"></param>
        /// <returns>服务器返回字符串</returns>
        public static string PostData(string url, string data, Encoding encoding)
        {
            byte[] postBytes = encoding.GetBytes(data);

            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded;charset=" + encoding.WebName;
            req.ContentLength = postBytes.Length;

            try
            {
                using (Stream reqStream = req.GetRequestStream())
                {
                    reqStream.Write(postBytes, 0, postBytes.Length);
                }

                using (WebResponse res = req.GetResponse())
                {
                    using (StreamReader sr = new StreamReader(res.GetResponseStream(), encoding))
                    {
                        string strResult = sr.ReadToEnd();
                        return strResult;
                    }
                }

            }
            catch (WebException ex)
            {
                return "无法连接到服务器\r\n错误信息：" + ex.Message;
            }

        }

        /// <summary>
        /// 从目标url，Get数据
        /// </summary>
        /// <param name="url"></param>
        /// <param name="data"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string GetData(string url, string data, Encoding encoding)
        {
            string address = url;
            if (!String.IsNullOrEmpty(data))
            {
                address = url + "?" + data;
            }

            Uri uri = new Uri(address);
            WebRequest webReq = WebRequest.Create(uri);

            try
            {
                using (HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse())
                {
                    using (Stream respStream = webResp.GetResponseStream())
                    {
                        using (StreamReader objReader = new StreamReader(respStream, encoding))
                        {
                            string strRes = objReader.ReadToEnd();
                            return strRes;
                        }
                    }
                }
            }
            catch (WebException ex)
            {
                return "无法连接到服务器/r/n错误信息：" + ex.Message;
            }
        }

        #endregion

        #region Cookies

        /// <summary>
        /// 设置客户端cookie（有效期一年）
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void SetCookie(string key, string value)
        {
            SetCookie(key, value, 30);
        }

        /// <summary>
        /// 设置客户端cookie（有效期一年）
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void SetCookie(string key, object value)
        {
            SetCookie(key, value, 30);
        }

        /// <summary>
        /// 设置客户端Cookie
        /// </summary>
        /// <param name="key">cookie名称</param>
        /// <param name="value">cookie值</param>
        /// <param name="expireDays"></param>
        public static void SetCookie(string key, object value, double expireDays)
        {
            string str = string.Empty;
            if (value != null && !String.IsNullOrEmpty(value.ToString()))
            {
                str = Light.Utility.Security.Base64StringCryptor.Encrypt(value.ToString(), "aeogep");
            }
            HttpCookie cookie = new HttpCookie(key, str);
            cookie.Expires = DateTime.Now.AddDays(expireDays);
            HttpContext.Current.Response.Cookies.Add(cookie);
        }

        /// <summary>
        /// 取出Cookie
        /// </summary>
        /// <param name="key">cookie名称</param>
        /// <returns></returns>
        public static string GetCookie(string key)
        {
            string value = string.Empty;

            string cipher = HttpContext.Current.Request.Cookies[key] != null ? HttpContext.Current.Request.Cookies[key].Value : string.Empty;
            if (!String.IsNullOrEmpty(cipher))
            {
                value = Light.Utility.Security.Base64StringCryptor.Decrypt(cipher, "aeogep");
            }
            return value;
        }


        public static string GetCookie(string key, string defaultValue)
        {
            string value = GetCookie(key);
            if (String.IsNullOrEmpty(value))
                value = defaultValue;
            return value;
        }

        public static int GetCookie(string key, int defalutValue)
        {
            int result = defalutValue;

            string value = GetCookie(key);
            if (!String.IsNullOrEmpty(value))
                result = StringHelper.ToInt(value);

            return result;
        }

        public static decimal GetCookie(string key, decimal defalutValue)
        {
            decimal result = defalutValue;

            string value = GetCookie(key);
            if (!String.IsNullOrEmpty(value))
                result = StringHelper.ToDecimal(value);

            return result;
        }

        public static bool GetCookie(string key, bool defalutValue)
        {
            bool result = defalutValue;

            string value = GetCookie(key);
            if (!String.IsNullOrEmpty(value))
                result = Boolean.Parse(value);

            return result;
        }

        #endregion

        #region Session

        public static void SetSession(string name, object value)
        {
            if (System.Web.HttpContext.Current != null)
                System.Web.HttpContext.Current.Session[name] = value;
        }

        public static string GetSession(string name)
        {
            if (System.Web.HttpContext.Current != null)
                return System.Web.HttpContext.Current.Session[name] as String;
            else
                return string.Empty;
        }

        public static string GetSession(string name, string defaultValue)
        {
            string value = GetSession(name);
            if (String.IsNullOrEmpty(value))
                value = defaultValue;
            return value;
        }

        public static T GetSession<T>(string name)
        {
            T result = default(T);

            try
            {
                if (System.Web.HttpContext.Current != null)
                    result = (T)System.Web.HttpContext.Current.Session[name];
            }
            catch
            {
                result = default(T);
            }

            return result;

        }

        public static T GetSession<T>(string name, T defaultValue)
        {
            T value = GetSession<T>(name);
            if (value == null || value.Equals(default(T)))
                value = defaultValue;
            return value;
        }

        #endregion

        #region 获取IP地址归属地信息

        /// <summary>
        /// 获取当前请求来源IP归属地信息
        /// </summary>
        /// <returns></returns>
        public static string GetBelongsInfo()
        {
            return GetBelongsInfo(HttpContext.Current.Request.UserHostAddress);
        }

        /// <summary>
        /// 获取IP地址归属地
        /// </summary>
        /// <param name="strIPAddress"></param>
        /// <returns>例：广东省深圳市 移动</returns>
        public static string GetBelongsInfo(string strIPAddress)
        {
            string s = WebHelper.GetData("http://www.ip138.com/ips1388.asp?ip=" + strIPAddress + "&action=2", null, Encoding.GetEncoding("gb2312"));

            int a = s.IndexOf("本站主数据：") + "本站主数据：".Length;
            int b = s.IndexOf("参考数据一");

            if ((b - a) > 0)
            {
                return s.Substring(a, b - a).Replace("</li><li>", "");
            }

            return string.Empty;
        }

        /// <summary>
        /// 获取当前请求来源IP地址所在城市
        /// </summary>
        /// <returns></returns>
        public static string GetBelongsCity()
        {
            return GetBelongsCity(HttpContext.Current.Request.UserHostAddress);
        }

        /// <summary>
        /// 获取IP地址所在城市
        /// </summary>
        /// <param name="strIPAddress"></param>
        /// <returns></returns>
        public static string GetBelongsCity(string strIPAddress)
        {
            string city = string.Empty;


            string info = GetBelongsInfo(strIPAddress);
            int a = info.IndexOf("省") + 1;
            int b = info.IndexOf("市");
            if ((b - a) > 0)
            {
                city = info.Substring(a, b - a);
            }
            return city;
        }

        /// <summary>
        /// 获取当前请求来源IP地址所在省份
        /// </summary>
        /// <returns></returns>
        public static string GetBelongsProvince()
        {
            return GetBelongsProvince(HttpContext.Current.Request.UserHostAddress);
        }

        /// <summary>
        /// 获取IP地址所在省份
        /// </summary>
        /// <param name="strIPAddress"></param>
        /// <returns></returns>
        public static string GetBelongsProvince(string strIPAddress)
        {
            string city = string.Empty;


            string info = GetBelongsInfo(strIPAddress);
            int a = info.IndexOf("省") + 1;
            if (a > 0)//省份
            {
                city = info.Substring(0, a);
            }
            else//直辖市
            {
                a = info.IndexOf("市") + 1;
                if (a > 0)
                {
                    city = info.Substring(0, a);
                }
                else
                {
                    a = info.IndexOf("自治") + 1;
                    city = info.Substring(0, a);
                }
            }
            return city;
        }

        public static string GetCurrentRequestIP()
        {
            return HttpContext.Current.Request.UserHostAddress;
        }

        #endregion


        public static bool IsRequest(string name)
        {
            return !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[name])
                || !String.IsNullOrEmpty(HttpContext.Current.Request[name]);
        }

        public static bool IsRequest(string key, string value)
        {
            bool result = HttpContext.Current.Request.QueryString[key] == value;
            if (!result)
            {
                result = HttpContext.Current.Request[key] == value;
            }
            return result;
        }

        public static string Request(string name)
        {
            string str = HttpContext.Current.Request[name];
            if (String.IsNullOrEmpty(str))
            {
                str = HttpContext.Current.Request.QueryString[name];
            }
            return str;
        }

        public static int GetRequest(string name, int defaultValue)
        {
            int result = defaultValue;

            string value = Request(name);
            if (!String.IsNullOrEmpty(value) && StringHelper.IsNumeric(value))
                result = StringHelper.ToInt(value);

            return result;
        }

        public static decimal GetRequest(string name, decimal defaultValue)
        {
            decimal result = defaultValue;

            string value = Request(name);
            if (!String.IsNullOrEmpty(value) && StringHelper.IsNumeric(value))
                result = StringHelper.ToDecimal(value);

            return result;
        }


        public static string GetRequest(string name, string defaultValue)
        {
            string result = defaultValue;

            string value = Request(name);
            if (!String.IsNullOrEmpty(value))
                result = value;
            return result;
        }


        /// <summary>
        /// Http当前上下文
        /// </summary>
        public static HttpContext CurContext
        {
            get
            {
                return HttpContext.Current;
            }
        }


        /// <summary>
        /// aspx页面静态化
        /// </summary>
        /// <param name="aspxUrl"></param>
        /// <param name="staticUrl"></param>
        /// <param name="encoding"></param>
        public static void StaticPage(string aspxUrl, string staticUrl, Encoding encoding)
        {
            try
            {
                System.IO.StringWriter swHtml = new System.IO.StringWriter();
                HttpContext.Current.Server.Execute(aspxUrl, swHtml);
                string contentStr = swHtml.ToString();

                System.IO.StreamWriter sWriter = new System.IO.StreamWriter(staticUrl, false, encoding);
                sWriter.Write(contentStr);
                sWriter.Close();
            }
            catch (Exception ex)
            {
                throw new Exception("页面静态化 Light.Utility.WebHelper.StaticPage 失败:" + ex.Message);
            }

        }

        /// <summary>
        /// 获取当前请求生成一个令牌
        /// </summary>
        /// <returns></returns>
        public static string CreateAccessToken()
        {
            string data = CurContext.Request.UserAgent + "※" + CurContext.Request.UserHostAddress + "※" + DateTime.Now.ToString("yyyyMMdd");
            return Serializer.CreateMD5(data).Replace("-", "").ToLower();
        }

        /// <summary>
        /// 验证令牌是否合法
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool ValidateAccessToken(string token)
        {
            string newToken = CreateAccessToken();
            return newToken == token;
        }


        /// <summary>
        /// 从当前请求中获取客户端Post数据
        /// </summary>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string GetPostData(Encoding encoding)
        {
            Stream stream = WebHelper.CurContext.Request.InputStream;
            byte[] b = new byte[stream.Length];
            stream.Read(b, 0, (int)stream.Length);
            return encoding.GetString(b);
        }

        /// <summary>
        /// 是否为Post请求
        /// </summary>
        public static bool IsPostRequest
        {
            get
            {
                return WebHelper.CurContext.Request.HttpMethod.ToLower() == "post";
            }
        }

        /// <summary>
        /// 是否为Get请求
        /// </summary>
        public static bool IsGetRequest
        {
            get
            {
                return WebHelper.CurContext.Request.HttpMethod.ToLower() == "get";
            }
        }

        //获取客户端设备信息
        public static string GetDevice()
        {
            string userAgent = WebHelper.CurContext.Request.UserAgent;

            if (userAgent.IndexOf("Android") > -1)
                return "Android";
            else if (userAgent.IndexOf("iPhone") > -1)
                return "iPhone";
            else if (userAgent.IndexOf("iPad") > -1)
                return "iPad";
            else
                return "PC";
        }

        /// <summary>
        /// 是否
        /// </summary>
        /// <returns></returns>
        public static bool IsMobileDevice()
        {
            //string device = GetDevice();
            //return device != "PC";

            return WebHelper.CurContext.Request.RawUrl.IndexOf(".ashx") > -1;
        }
    }
}
